<script setup lang="ts">
import { ref, watch, onMounted } from 'vue'
import { ElUpload, ElButton, ElImage, ElIcon, ElMessage, ElDialog } from 'element-plus'
import type { UploadRequestHandler } from 'element-plus'
import { $t } from '@vben/locales';
import ImagePreviewActions from './image-preview-actions.vue'

defineOptions({ name: 'StemImageUpload' })

interface ImageItem {
  file?: File
  path?: string
  url?: string
  name?: string
  id?: string
}

const props = defineProps<{
  stemImages: Array<ImageItem>
}>()
const emit = defineEmits(['update:stemImages'])

// 内部图片列表
const internalImageList = ref<Array<ImageItem>>([])

// 预览对话框
const previewVisible = ref(false)
const previewImageUrl = ref('')

// 初始化数据
onMounted(() => {
  if (props.stemImages && Array.isArray(props.stemImages)) {
    internalImageList.value = props.stemImages.map((item) => ({
      ...item,
      id: item.id || `img_${Date.now()}_${Math.random()}`,
      url: item.url || (item.file ? URL.createObjectURL(item.file) : '')
    }))
  }
})

// 监听外部数据变化，但只在必要时更新
watch(() => props.stemImages, (newVal) => {
  if (newVal?.length) {
    internalImageList.value = newVal
  } else {
    internalImageList.value = []
  }
}, { deep: true })

// 上传前检查
const beforeUpload = (rawFile: File) => {
  const isValidType = ['image/bmp', 'image/png', 'image/jpeg', 'image/jpg'].includes(rawFile.type)
  const isLt5M = rawFile.size / 1024 / 1024 < 5

  if (!isValidType) {
    ElMessage.error($t('common.imageFormatTxt'))
    return false
  }
  if (!isLt5M) {
    ElMessage.error($t('common.imageSizeLimitTxt', ['5']))
    return false
  }
  return true
}

// 处理上传
const handleUpload: UploadRequestHandler = (options) => {
  const { file } = options
  const newImage: ImageItem = {
    file,
    path: file.name,
    url: URL.createObjectURL(file),
    name: file.name,
    id: `img_${Date.now()}_${Math.random()}`
  }
  // 添加到内部列表
  internalImageList.value.push(newImage)

  // 发出更新事件
  emitUpdate()

  return Promise.resolve()
}

// 删除图片
const deleteImage = (id: string) => {
  const index = internalImageList.value.findIndex(item => item.id === id)
  if (index > -1) {
    // 释放URL对象内存
    const item = internalImageList.value[index]
    if (item && item.url && item.url.startsWith('blob:')) {
      URL.revokeObjectURL(item.url)
    }

    // 从内部列表删除
    internalImageList.value.splice(index, 1)

    // 发出更新事件
    emitUpdate()
  }
}

// 统一的更新方法
const emitUpdate = () => {
  // 创建一个新数组，确保每个项目都有必要的属性
  const updatedList = internalImageList.value.map(item => ({
    file: item.file,
    path: item.path,
    url: item.url,
    name: item.name,
    id: item.id
  }))

  emit('update:stemImages', updatedList)
}

// 预览图片
const previewImage = (url: string) => {
  previewImageUrl.value = url
  previewVisible.value = true
}

// 获取上传数据
const getData = () => {
  return internalImageList.value
}

defineExpose({
  getData
})
</script>

<template>
  <div class="w-full">
    <!-- 提示信息 -->
    <div class="text-[#AEAEAE] text-xs leading-relaxed pr-3 py-2">
      {{ $t('questionBank.stemImageUploadTip') }}
    </div>

    <!-- 上传区域 -->
    <div class="flex items-start flex-wrap gap-3">
      <!-- 已上传的图片列表 -->
      <div v-for="image in internalImageList" :key="image.id"
        class="relative w-28 h-16 rounded border border-gray-300 overflow-hidden group transition-shadow">
        <el-image :src="image.url" :alt="image.name" class="w-full h-full cursor-pointer" fit="contain"
          @click="previewImage(image.url!)" />
        <ImagePreviewActions :image-url="image.url!" @preview="previewImage(image.url!)"
          @delete="deleteImage(image.id!)" />
      </div>

      <!-- 上传按钮 -->
      <el-upload action="#" :http-request="handleUpload" :before-upload="beforeUpload"
        accept="image/bmp,image/png,image/jpeg,image/jpg" :auto-upload="true" :show-file-list="false">
        <div
          class="w-28 h-16 border-[1px] border-gray-300 rounded flex flex-col items-center justify-center cursor-pointer transition-all duration-300 hover:border-blue-500 hover:text-blue-500">
          <div class="text-xl mb-1">+</div>
          <div class="text-xs text-gray-600">{{ $t('questionBank.uploadImageButton') }}</div>
        </div>
      </el-upload>
    </div>

    <!-- 预览对话框 -->
    <el-dialog v-model="previewVisible" :title="$t('questionBank.imagePreview')" width="500px" center>
      <div class="flex justify-center items-center">
        <el-image :src="previewImageUrl" fit="contain" style="width: 100%;width:500px" />
      </div>
    </el-dialog>
  </div>
</template>
